Stone theorem for norm-continuous unitary one-parameter groups - #1510
Stone theorem for norm-continuous unitary one-parameter groups#1510TomOleDiem wants to merge 13 commits into
Conversation
…ne-parameter groups) Physlib/Mathematics/OneParameterSubgroups/Basic.lean (new): - OneParameterSubgroup.existsUnique_generator: every continuous one-parameter subgroup of a real Banach algebra's unit group is exp(t . A) for a unique generator A. Pure Banach-algebra content, no physics, reusable well beyond quantum mechanics. Physlib/Mathematics/OneParameterSubgroups/Matrix.lean (new): - Specializes the above to complex matrices via the Frobenius norm, identifying real scalar multiplication with multiplication by real complex numbers. Physlib/QuantumMechanics/Stone.lean (new): - Matrix.UnitaryOneParameterSubgroup and the finite-dimensional Stone correspondence: a continuous one-parameter subgroup of U(n) has a unique anti-Hermitian generator A (equivalently, after multiplying by i, a unique Hermitian generator H with U(t) = exp(-itH)) -- existsUnique_antiHermitian_generator / existsUnique_hermitian_generator. - The converse direction, ofHermitian: every Hermitian H genuinely generates a continuous U(n)-valued one-parameter subgroup t -> exp(-itH), bundled as a real ContinuousMonoidHom (built via MonoidHom.codRestrict + Continuous.subtype_mk, sidestepping Mathlib's lack of a canonical matrix norm by routing the exp-additivity/continuity proofs through Matrix.exp_add_of_commute's own `open scoped Norms.Operator` pattern rather than the ambient default instance). - stoneEquiv: the finite-dimensional statement of Stone's theorem itself, as a genuine Equiv between U(n)'s continuous one-parameter subgroups and the Hermitian n x n matrices -- the algebraic reason a Hermitian Hamiltonian generates unitary time evolution, specialized to finite-level (e.g. qubit) quantum systems. All new theorems kernel-checked (#print axioms): only propext, Classical.choice, Quot.sound. Zero sorry.
…bra instance - Basic.lean: the module doc referenced a now-deleted Unitary.lean; point it at Physlib.QuantumMechanics.Stone instead. Drop private from all 8 internal lemmas (ambientValue and friends) -- physlib's module system makes private declarations brittle, and there's no reason these helper lemmas need to be hidden. Hoist the NormedAlgebra ℚ E instance (needed for NormedSpace.exp's API) to a single local instance declared once, instead of duplicating the same 'let +nondep' inline in both exists_generator_of_nontrivial and existsUnique_generator. - Stone.lean: add a reference to Stone's original 1932 theorem. Re-verified: targeted build of all 3 files, full Physlib aggregate build, #print axioms on the 6 key public theorems (only propext/Classical.choice/ Quot.sound), and empty sorry/private greps -- all clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Thank you for this pull-request (PR). If this is your first PR, welcome to the community! Below is what will happen next. Please read carefully if you are not familiar with the process. You may open other PRs while this one is being reviewed, and can stack PRs on top of each other, so don't let these steps slow you down.
Tip: The easiest way to get have a fast review is to submit a PR that is small and self-contained, and has clear documentation explaining why things are the way they are in your chages. If you have any problems or questions, please reach out to the community on the Zulip. |
Document the helper definitions and remove the unused Fintype assumption from Matrix.IsAntiHermitian. Co-authored-by: Claude Opus 4.8 <no-reply+claude-opus-4-8@anthropic.com>
|
Many thanks for this PR.
|
|
awaiting-author |
Use lemma declarations throughout and remove imports reported as redundant by Mathlib's import analysis. Co-authored-by: Claude Opus 4.8 <no-reply+claude-opus-4-8@anthropic.com>
|
The final result here is really great work. Though, I do have a couple of concerns that still make it a bit hard to review in its current form:
|
Use the physical exp(-itH/ℏ) normalization, connect the result to FiniteTarget time evolution, and explain its scope relative to unbounded QuantumSystem Hamiltonians. Co-authored-by: Claude Opus 4.8 <no-reply+claude-opus-4-8@anthropic.com>
Present only the physically normalized Hamiltonian statement in the module overview. Co-authored-by: Claude Opus 4.8 <no-reply+claude-opus-4-8@anthropic.com>
Fold the anti-Hermitian and natural-units existence arguments into existsUnique_hamiltonian so the public API has one generator theorem normalized by ℏ. Co-authored-by: Claude Opus 4.8 <no-reply+claude-opus-4-8@anthropic.com>
Co-authored-by: Claude Opus 4.8 <no-reply+claude-opus-4-8@anthropic.com>
Co-authored-by: Claude Opus 4.8 <no-reply+claude-opus-4-8@anthropic.com>
|
Thanks for your patience. I am still getting familiar with Lean and with Physlib’s file and folder structure. I have reworked It now works with bounded operators on a Hilbert space and is connected directly to I have left the two underlying one-parameter subgroup files under |
|
-awaiting-author |
|
awaiting-author |
gloges
left a comment
There was a problem hiding this comment.
Thanks for making headway on Stone's theorem!
There is a lot that needs to be cleaned up to best utilize the existing Mathlib machinery and reduce redundancy. The fundamental issue is that these results should be phrased in terms of AddChar, not the MonoidHomClass/Multiplicative combo currently being used.
|
Thanks for all these comments. I have reworked the PR to incorporate the feedback:
Thanks again for the detailed guidance. -awaiting-author |
gloges
left a comment
There was a problem hiding this comment.
Thanks, things look much better now with AddChar!
I've made another pass through making comments/suggests - at this point those for OneParameterSubgroups are more stylistic and should help to improve the proofs (this will make life easier in the future).
There was a problem hiding this comment.
I don't think we should limit ourselves to only time evolution/Hamiltonians since everything in this file applies equally well, for example, to translation/momenta.
Also, throughout the file you are casting U t to type H →L[ℂ] H. This suggests to me that the CoeFun needs to be changed or the definition adjusted to something like
structure UnitaryFoo (H : Type*) [NormedAddCommGroup H] [InnerProductSpace ℂ H]
[CompleteSpace H] where
/-- The additive character sending time to its unitary evolution operator. -/
toAddChar : AddChar ℝ (H →L[ℂ] H)
/-- foo -/
selfAdjoint : ∀ t, IsSelfAdjoint (toAddChar t)
/-- Time evolution is continuous in the operator norm. -/
continuous : Continuous toAddChar|
Thanks for all the detailed comments. I made a final structural pass through the PR and reworked the result around the more general object. The central definition is now The long Hamiltonians are now treated as the time-translation specialization rather than as part of the general theorem. I also incorporated the proof-structure suggestions in This seems to give a cleaner separation between the reusable Stone correspondence and its physical interpretation as time evolution. I am happy to adjust the placement or naming if you would prefer a different organization. -awaiting-author |
gloges
left a comment
There was a problem hiding this comment.
A few minor suggestions for OneParameterSubgroups/Basic.lean.
Even more than before I think that the definition of UnitaryOneParameterGroup is not yet optimal - I've played around a bit with it and have left my suggestion below.
Also, a general comment is that many of the dsimp and change lines can simply be removed.
| ∃ d : ℝ, 0 < d ∧ IsUnit (∫ x in (0 : ℝ)..d, U x) := by | ||
| let c : ℝ := ‖(1 : E)‖⁻¹ / 2 | ||
| have hone : 0 < ‖(1 : E)‖ := norm_pos_iff.mpr one_ne_zero | ||
| have hc : 0 < c := by dsimp [c]; positivity |
There was a problem hiding this comment.
| have hc : 0 < c := by dsimp [c]; positivity | |
| have hc : 0 < c := by positivity |
| rw [Metric.eventually_nhds_iff] at hevent | ||
| obtain ⟨r, hr, hrU⟩ := hevent | ||
| let d := r / 2 | ||
| have hd : 0 < d := by dsimp [d]; positivity |
There was a problem hiding this comment.
| have hd : 0 < d := by dsimp [d]; positivity | |
| have hd : 0 < d := by positivity |
| calc | ||
| ‖(∫ x in (0 : ℝ)..d, U x) - (q : E)‖ = | ||
| ‖(∫ x in (0 : ℝ)..d, U x) - d • (1 : E)‖ := rfl | ||
| _ = ‖(∫ x in (0 : ℝ)..d, U x) - ∫ _x in (0 : ℝ)..d, (1 : E)‖ := by |
There was a problem hiding this comment.
| calc | |
| ‖(∫ x in (0 : ℝ)..d, U x) - (q : E)‖ = | |
| ‖(∫ x in (0 : ℝ)..d, U x) - d • (1 : E)‖ := rfl | |
| _ = ‖(∫ x in (0 : ℝ)..d, U x) - ∫ _x in (0 : ℝ)..d, (1 : E)‖ := by | |
| calc | |
| _ = ‖(∫ x in (0 : ℝ)..d, U x) - d • (1 : E)‖ := rfl | |
| _ = ‖(∫ x in (0 : ℝ)..d, U x) - ∫ _x in (0 : ℝ)..d, (1 : E)‖ := by |
| _ ≤ c * d := by | ||
| calc | ||
| _ ≤ c * |d - 0| := intervalIntegral.norm_integral_le_of_norm_le_const (fun x hx => by | ||
| apply le_of_lt | ||
| apply hrU | ||
| rw [Real.dist_0_eq_abs] | ||
| rw [Set.uIoc_of_le hd.le] at hx | ||
| rw [abs_of_nonneg hx.1.le] | ||
| exact hx.2.trans_lt (by dsimp [d]; linarith)) | ||
| _ = c * d := by rw [sub_zero, abs_of_pos hd] |
There was a problem hiding this comment.
| _ ≤ c * d := by | |
| calc | |
| _ ≤ c * |d - 0| := intervalIntegral.norm_integral_le_of_norm_le_const (fun x hx => by | |
| apply le_of_lt | |
| apply hrU | |
| rw [Real.dist_0_eq_abs] | |
| rw [Set.uIoc_of_le hd.le] at hx | |
| rw [abs_of_nonneg hx.1.le] | |
| exact hx.2.trans_lt (by dsimp [d]; linarith)) | |
| _ = c * d := by rw [sub_zero, abs_of_pos hd] | |
| _ ≤ c * |d - 0| := sorry | |
| _ = c * d := by rw [sub_zero, abs_of_pos hd] |
No need to nest calc blocks like this - add intermediate steps if they are useful!
| _ < ‖(↑q⁻¹ : E)‖⁻¹ := by | ||
| have hright : ‖(↑q⁻¹ : E)‖⁻¹ = d * ‖(1 : E)‖⁻¹ := by | ||
| change ‖d⁻¹ • (1 : E)‖⁻¹ = _ | ||
| rw [norm_smul, Real.norm_eq_abs, abs_inv, abs_of_pos hd] | ||
| field_simp | ||
| rw [hright] | ||
| dsimp [c] | ||
| nlinarith [inv_pos.mpr hone] |
There was a problem hiding this comment.
| _ < ‖(↑q⁻¹ : E)‖⁻¹ := by | |
| have hright : ‖(↑q⁻¹ : E)‖⁻¹ = d * ‖(1 : E)‖⁻¹ := by | |
| change ‖d⁻¹ • (1 : E)‖⁻¹ = _ | |
| rw [norm_smul, Real.norm_eq_abs, abs_inv, abs_of_pos hd] | |
| field_simp | |
| rw [hright] | |
| dsimp [c] | |
| nlinarith [inv_pos.mpr hone] | |
| _ < d * ‖(1 : E)‖⁻¹ := by dsimp [c]; nlinarith [inv_pos.mpr hone] | |
| _ = ‖q.inv‖⁻¹ := by simp [q, norm_smul, mul_comm, abs_of_pos hd] |
Same here.
| let L : E →L[ℝ] E := | ||
| (LinearMap.mulLeft ℝ (U s)).mkContinuous ‖U s‖ (fun x => norm_mul_le _ _) | ||
| calc | ||
| U s * ∫ x in (0 : ℝ)..t, U x = L (∫ x in (0 : ℝ)..t, U x) := rfl | ||
| _ = ∫ x in (0 : ℝ)..t, L (U x) := |
There was a problem hiding this comment.
| let L : E →L[ℝ] E := | |
| (LinearMap.mulLeft ℝ (U s)).mkContinuous ‖U s‖ (fun x => norm_mul_le _ _) | |
| calc | |
| U s * ∫ x in (0 : ℝ)..t, U x = L (∫ x in (0 : ℝ)..t, U x) := rfl | |
| _ = ∫ x in (0 : ℝ)..t, L (U x) := | |
| let L : E →L[ℝ] E := (LinearMap.mulLeft ℝ (U s)).mkContinuous ‖U s‖ (fun x => norm_mul_le _ _) | |
| calc | |
| _ = L (∫ x in (0 : ℝ)..t, U x) := rfl | |
| _ = ∫ x in (0 : ℝ)..t, L (U x) := |
Best to keep the =/≤/≥ aligned in calc.
| /-- A norm-continuous unitary one-parameter group on a complex Hilbert space. -/ | ||
| structure UnitaryOneParameterGroup (H : Type*) [NormedAddCommGroup H] [InnerProductSpace ℂ H] | ||
| [CompleteSpace H] where | ||
| /-- The additive character from the real parameter to unitary operators. -/ | ||
| toAddChar : AddChar ℝ (unitary (H →L[ℂ] H)) | ||
| /-- The group is continuous in the operator norm. -/ | ||
| continuous : Continuous toAddChar | ||
|
|
||
| namespace UnitaryOneParameterGroup | ||
|
|
||
| variable {H : Type*} [NormedAddCommGroup H] [InnerProductSpace ℂ H] [CompleteSpace H] | ||
|
|
||
| instance : CoeFun (UnitaryOneParameterGroup H) fun _ => ℝ → (H →L[ℂ] H) := | ||
| ⟨fun U t => U.toAddChar t⟩ | ||
|
|
||
| /-- The operator-valued additive character underlying a unitary one-parameter group. -/ | ||
| def operatorAddChar (U : UnitaryOneParameterGroup H) : AddChar ℝ (H →L[ℂ] H) := | ||
| (unitary (H →L[ℂ] H)).subtype.compAddChar U.toAddChar |
There was a problem hiding this comment.
Again, that you find it necessary to define operatorAddChar suggests that the definition of UnitaryOneParameterGroup is not yet "correct" (in the sense of best serving its use cases).
I've tinkered a bit with this and feel strongly that the starting point should be
| /-- A norm-continuous unitary one-parameter group on a complex Hilbert space. -/ | |
| structure UnitaryOneParameterGroup (H : Type*) [NormedAddCommGroup H] [InnerProductSpace ℂ H] | |
| [CompleteSpace H] where | |
| /-- The additive character from the real parameter to unitary operators. -/ | |
| toAddChar : AddChar ℝ (unitary (H →L[ℂ] H)) | |
| /-- The group is continuous in the operator norm. -/ | |
| continuous : Continuous toAddChar | |
| namespace UnitaryOneParameterGroup | |
| variable {H : Type*} [NormedAddCommGroup H] [InnerProductSpace ℂ H] [CompleteSpace H] | |
| instance : CoeFun (UnitaryOneParameterGroup H) fun _ => ℝ → (H →L[ℂ] H) := | |
| ⟨fun U t => U.toAddChar t⟩ | |
| /-- The operator-valued additive character underlying a unitary one-parameter group. -/ | |
| def operatorAddChar (U : UnitaryOneParameterGroup H) : AddChar ℝ (H →L[ℂ] H) := | |
| (unitary (H →L[ℂ] H)).subtype.compAddChar U.toAddChar | |
| /-- A norm-continuous unitary one-parameter group on a complex Hilbert space. -/ | |
| structure UnitaryOneParameterGroup (H : Type*) [NormedAddCommGroup H] [InnerProductSpace ℂ H] | |
| [CompleteSpace H] where | |
| /-- The additive character from the real parameter to unitary operators. -/ | |
| toAddChar : AddChar ℝ (H →L[ℂ] H) | |
| /-- foo -/ | |
| mem_unitary : ∀ t, toAddChar t ∈ unitary (H →L[ℂ] H) | |
| /-- The group is continuous in the operator norm. -/ | |
| continuous : Continuous toAddChar | |
| namespace UnitaryOneParameterGroup | |
| variable {H : Type*} [NormedAddCommGroup H] [InnerProductSpace ℂ H] [CompleteSpace H] | |
| attribute [coe] UnitaryOneParameterGroup.toAddChar | |
| instance : CoeFun (UnitaryOneParameterGroup H) fun _ => ℝ → (H →L[ℂ] H) := ⟨fun U => U.toAddChar⟩ |
(I think early I mistakenly wrote something like this with self-adjoint in place of unitary - sorry for the confusion! If something doesn't make sense please feel free to ask.) See below for an example of how the unitary property can be used in proofs.
| @[simp] | ||
| lemma adjoint_eq (U : UnitaryOneParameterGroup H) (t : ℝ) : | ||
| ContinuousLinearMap.adjoint (U t) = U (-t) := by | ||
| change star (U t) = U (-t) | ||
| apply left_inv_eq_right_inv (U.toAddChar t).property.1 | ||
| have h := congrArg Subtype.val (U.toAddChar.map_add_eq_mul t (-t)) | ||
| simpa using h.symm |
There was a problem hiding this comment.
| @[simp] | |
| lemma adjoint_eq (U : UnitaryOneParameterGroup H) (t : ℝ) : | |
| ContinuousLinearMap.adjoint (U t) = U (-t) := by | |
| change star (U t) = U (-t) | |
| apply left_inv_eq_right_inv (U.toAddChar t).property.1 | |
| have h := congrArg Subtype.val (U.toAddChar.map_add_eq_mul t (-t)) | |
| simpa using h.symm | |
| @[simp] | |
| lemma adjoint_eq (U : UnitaryOneParameterGroup H) (t : ℝ) : (U t).adjoint = U (-t) := by | |
| apply left_inv_eq_right_inv <| star_mul_self_of_mem <| U.mem_unitary t | |
| simp [← AddChar.map_add_eq_mul] |
An example of using UnitaryOneParameterGroup.mem_unitary.
| /-- The bounded self-adjoint generator of `U`, in the convention `U(t) = exp (-itA)`. -/ | ||
| noncomputable def generator (U : UnitaryOneParameterGroup H) : H →L[ℂ] H := | ||
| Complex.I • deriv U.operatorAddChar 0 |
There was a problem hiding this comment.
This is a good idea! You can probably just write deriv U 0, making use of the coercions.
| lemma deriv_star_eq_neg (U : UnitaryOneParameterGroup H) : | ||
| star (deriv U.operatorAddChar 0) = -deriv U.operatorAddChar 0 := by |
There was a problem hiding this comment.
| lemma deriv_star_eq_neg (U : UnitaryOneParameterGroup H) : | |
| star (deriv U.operatorAddChar 0) = -deriv U.operatorAddChar 0 := by | |
| lemma adjoint_deriv_eq_neg (U : UnitaryOneParameterGroup H) : | |
| (deriv U 0).adjoint = -deriv U 0 := by |
|
Thanks for your suggestions! |
Summary
This PR proves the bounded-generator form of Stone theorem for norm-continuous unitary one-parameter groups.
OneParameterSubgroup.apply_eq_exp_smul_derivproves the underlying Banach-algebra result for a continuousAddChar.UnitaryOneParameterGroupbundles anAddCharinto the Mathlib unitary subgroup and coerces directly to bounded operators. Its canonical generator is self-adjoint, satisfiesU(t) = exp(-itA), and is unique. The converse construction andstoneEquivgive the correspondence.FiniteTarget.unitaryTimeEvolutionspecializes the general result to time translations. Its generator isH/ℏ, givingU(t) = exp(-itH/ℏ).The general unitary-group result is not specific to Hamiltonians: the same structure covers bounded generators of translations and rotations. The Hamiltonian interpretation therefore stays in
FiniteTarget, while the reusable correspondence lives underMathematics/OneParameterSubgroups.This is the norm-continuous/bounded case. The strongly continuous theorem with unbounded generators requires spectral theory that is not yet available in Physlib.